﻿using GodSharp;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using ZK.Common;
using ZK.Common.Log4;
using ZK.InterfaceServer;

namespace ZK.HardWareBLL
{
    /// <summary>
    /// 托利多地磅 -筒仓 
    ///型号 8140pro
    /// 
    /// 
    /// </summary>
    public class ToledoWagonBalanceTCBLL
    {
        private readonly GodSerialPort _serialPort;
        private bool _isOpened;//打开状态
        private List<double> weightList;
        public decimal weighNow = 0;
        int weightListCount;
        private HaredWareCommonM wagonBalance;
        List<byte> listInt;
        bool resB;

        private decimal? nowWeight = 0;
        public ToledoWagonBalanceTCBLL()
        {
            weightListCount = Convert.ToInt32(AppConfigHelper.GetAppSettings("weightListCount"));
            weightList = new List<double>();
            wagonBalance = IConfig.GetSetwagonBalance;
            listInt = new List<byte>();
            resB = true;

            try
            {

                _serialPort =
                    new GodSerialPort(wagonBalance.PortName, Convert.ToInt32(wagonBalance.BaudRate), Parity.Even, Convert.ToInt32(wagonBalance.DataBits), StopBits.Two)
                    {
                        EndCharOfHex = "00",
                        DataFormat = SerialPortDataFormat.Hex,
                        RtsEnable = true,
                        DtrEnable = true,
                    };
                _serialPort.UseDataReceived((serialPort, bytes) =>
                {

                    try
                    {
                        if (_serialPort.IsOpen)
                        {
                            resB = !resB;
                            listInt.AddRange(bytes.ToList());
                            if (resB)
                            {
                                List<byte> l = new List<byte>();
                                for (int i = 0; i < listInt.Count; i++)
                                {
                                    if (listInt[i] == 2)
                                    {
                                        l = listInt.Skip(i).Take(17).ToList();
                                        goto A;
                                    }
                                }
                            A:
                                listInt = new List<byte>();
                                //Common.Log4.LogManage.WriteInfo(string.Join("-", l));
                                decimal? weight = GetWeight(l);
                                if ((nowWeight != weight) && (ErrDate != weight))
                                {
                                    nowWeight = weight;
                                    Common.DelegateHelper.WeightCallbackEvent?.Invoke(Convert.ToDouble(weight));
                                }
                            }

                        }
                    }
                    catch (Exception ex)
                    {
                        LogManage.WriteErr("获取地磅数据异常：" + ex.ToString());
                        Common.DelegateHelper.InfoMessageEvent?.Invoke("获取地磅数据异常");
                    }
                });
                Open();
            }
            catch (Exception ex)
            {
                AutoControlTransportApiServer.AddHardWareLog(wagonBalance.Name, 1, "串口通讯失败");
                Common.Log4.LogManage.WriteErr("初始化地磅 " + ex.ToString());
                Common.DelegateHelper.InfoMessageEvent?.Invoke("初始化地磅失败！");
                //  Common.MessageDialog.MessageBoxShow("地磅数据异常！");
            }
        }

        private int ErrDate = -1;
        /// <summary>
        /// 获取地磅数据
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        private decimal? GetWeight(List<byte> bytes)
        {
            if (bytes.Count == 17)
            {
                decimal number = 0;

                number += (bytes[4] - 48) * 100000;
                number += (bytes[5] - 48) * 10000;
                number += (bytes[6] - 48) * 1000;
                number += (bytes[7] - 48) * 100;
                number += (bytes[8] - 48) * 10;
                number += (bytes[9] - 48);
                //Common.Log4.LogManage.WriteInfo((number / 1000).ToString());
                return (decimal)number / 1000;
            }
            else
            {
                // Common.Log4.LogManage.WriteErr("获取地磅数据长度有误 erroor" + string.Join("-", bytes));
                return -1;
            }
        }

        public static byte[] HexStringToByteArray(string s)
        {
            s = s.Replace(" ", "");
            byte[] buffer = new byte[s.Length / 2];
            for (int i = 0; i < s.Length; i += 2)
            {
                buffer[i / 2] = Convert.ToByte(s.Substring(i, 2), 0x10);
            }
            return buffer;
        }


        public static string ByteArrayToHexString(byte[] data)
        {
            StringBuilder builder = new StringBuilder(data.Length * 3);
            foreach (byte num in data)
            {
                builder.Append(Convert.ToString(num, 0x10).PadLeft(2, '0'));
            }
            return builder.ToString().ToUpper();
        }

        /// <summary>
        /// 打开地磅
        /// </summary>
        public void Open()
        {
            _isOpened = _serialPort.Open();
            if (!_isOpened)
            {
                LogManage.WriteErr("地磅打开失败 信息：" + Newtonsoft.Json.JsonConvert.SerializeObject(IConfig.GetSetwagonBalance));
                //MessageDialog.MessageBoxShow("地磅打开失败");
                AutoControlTransportApiServer.AddHardWareLog(wagonBalance.Name, 1, "地磅打开失败");
                Common.DelegateHelper.InfoMessageEvent.Invoke("地磅打开失败！");
            }
            //ReopenIfClosed();
        }
        /// <summary>
        /// 关闭地磅
        /// </summary>
        public void Close()
        {
            _isOpened = !_serialPort.Close();
        }
        /// <summary>
        /// 重新打开
        /// </summary>
        private void ReopenIfClosed()
        {
            if (_isOpened)
            {
                //await Task.Delay(1000);
                //await Task.Run(() =>
                //{
                //    if (!_serialPort.IsOpen)
                //    {
                //        _serialPort.Close();
                //        _serialPort.Open();
                //    }
                //    ReopenIfClosed();
                //});
            }
            else
            {
                _serialPort.Close();
            }
        }
    }
}
